#include "stdlib.hpp"
#include <purewell/filesystemstatus.hpp>

namespace purewell
{

#define _xchg(x) ((struct statvfs*)(x))
#define _cxchg(x) ((const struct statvfs*)(x))

size_t
PWFileSystemStatus::getBlockSize(void) const
{
#if __PW_HAVE_STATVFS_T
	return _cxchg(m_pData)->f_bsize;
#else
	return 0;
#endif
}

size_t
PWFileSystemStatus::getFragmentSize(void) const
{
#if __PW_HAVE_STATVFS_T
	return _cxchg(m_pData)->f_frsize;
#else
	return 0;
#endif
}

fsblkcnt_t
PWFileSystemStatus::getBlocks(void) const
{
#if __PW_HAVE_STATVFS_T
	return _cxchg(m_pData)->f_blocks;
#else
	return 0;
#endif
}

fsblkcnt_t
PWFileSystemStatus::getFreeBlocks(void) const
{
#if __PW_HAVE_STATVFS_T
	return _cxchg(m_pData)->f_bfree;
#else
	return 0;
#endif
}

fsblkcnt_t
PWFileSystemStatus::getAvailableBlocks(void) const
{
#if __PW_HAVE_STATVFS_T
	return _cxchg(m_pData)->f_bavail;
#else
	return 0;
#endif
}

fsblkcnt_t
PWFileSystemStatus::getINodes(void) const
{
#if __PW_HAVE_STATVFS_T
	return _cxchg(m_pData)->f_files;
#else
	return 0;
#endif
}

fsblkcnt_t
PWFileSystemStatus::getFreeINodes(void) const
{
#if __PW_HAVE_STATVFS_T
	return _cxchg(m_pData)->f_ffree;
#else
	return 0;
#endif
}

fsblkcnt_t
PWFileSystemStatus::getAvailableINodes(void) const
{
#if __PW_HAVE_STATVFS_T
	return _cxchg(m_pData)->f_favail;
#else
	return 0;
#endif
}

size_t
PWFileSystemStatus::getID(void) const
{
#if __PW_HAVE_STATVFS_T
	return _cxchg(m_pData)->f_fsid;
#else
	return 0;
#endif
}

size_t
PWFileSystemStatus::getFlags(void) const
{
#if __PW_HAVE_STATVFS_T
	return _cxchg(m_pData)->f_flag;
#else
	return 0;
#endif
}

size_t
PWFileSystemStatus::getMaxFileNameSize(void) const
{
#if __PW_HAVE_STATVFS_T
	return _cxchg(m_pData)->f_namemax;
#else
	return 0;
#endif
}

PWFileSystemStatus::PWFileSystemStatus()
{
	memset(m_pData, 0x00, PWFSSTAT_MAX_LEN);
}

PWFileSystemStatus::PWFileSystemStatus(const PWFileSystemStatus& fs)
{
	memcpy(m_pData, fs.m_pData, PWFSSTAT_MAX_LEN);
}

PWFileSystemStatus::PWFileSystemStatus(const char* path)
{
	getStatus(path);
}

PWFileSystemStatus::PWFileSystemStatus(int fd)
{
	getStatus(fd);
}

PWFileSystemStatus::PWFileSystemStatus(const PWFile& file)
{
	getStatus(file);
}

PWFileSystemStatus::~PWFileSystemStatus()
{
}

PWFileSystemStatus&
PWFileSystemStatus::operator = ( const PWFileSystemStatus& fs )
{
	memcpy(m_pData, fs.m_pData, PWFSSTAT_MAX_LEN);
	return *this;
}

bool
PWFileSystemStatus::getStatus(const PWFile& file)
{
#ifdef __PW_HAVE_FSTATVFS
	return 0 == fstatvfs(file.getHandle(), _xchg(m_pData));
#else
	return false;
#endif
}

bool
PWFileSystemStatus::getStatus(int fd)
{
#ifdef __PW_HAVE_FSTATVFS
	return 0 == fstatvfs(fd, _xchg(m_pData));
#else
	return false;
#endif
}

bool
PWFileSystemStatus::getStatus(const char* path)
{
#ifdef __PW_HAVE_STATVFS
	return 0 == statvfs(path, _xchg(m_pData));
#else
	return false;
#endif
}

bool
PWFileSystemStatus::isNoSUID(void) const
{
#if __PW_HAVE_STATVFS_T
	return 0 != ((_cxchg(m_pData)->f_flag)&ST_NOSUID);
#else
	return false;
#endif
}

bool
PWFileSystemStatus::isReadOnly(void) const
{
#if __PW_HAVE_STATVFS_T
	return 0 != ((_cxchg(m_pData)->f_flag)&ST_RDONLY);
#else
	return false;
#endif
}

};//namespace purewell

